package core;

import bgg4j.*;

import java.io.File;
import java.io.IOException;
import java.util.*;

import ui.WareHouse;

public class Library {
	
	private Bgg bgg = null;
	private String m_username = null;
	private List<CollectedGame> m_list_collection;
	private List<GameInfo> m_list_gameinfo;
	private List<GameInfo> m_wishlist_gameinfo;
	private List<WishGame> m_wishlist;
	private List<QueryResult> m_list_result;
	public static String HOMEDIR = ".MyGameWareHouse/";
	
	public Library(String username){
		bgg = new Bgg();
		bgg.setDir(Library.HOMEDIR);
		m_username = username;
	}
	
	public void search(String key, boolean isExact) throws BggException{
		m_list_result = bgg.getQueryResult(key, isExact);
	}
	
	public int getResultSize(){
		return m_list_result.size();
	}
	
	public Object[] getResultRawData(int index){
		QueryResult game = m_list_result.get(index);
		ResultRawData rawdata = new ResultRawData();
		rawdata.setGameID(game.getGameID());
		rawdata.setTitle(game.getName());
		rawdata.setYear(game.getYear());
		return rawdata.getRawData();
	}
	
	public String getBGGURL(){
		return bgg.getBaseURL();
	}
	
	public void setUserID(String username){
		m_username = username;
	}
	
	public int listSize(){
		return m_list_gameinfo.size();
	}
	
	public int wishListSize(){
		return m_wishlist.size();
	}
	
	public String getMyGameName(int gameID){
		String ret = null;
		for (CollectedGame game : m_list_collection){
			if (game.getGameID() == gameID){
				ret = game.getName();
				break;
			}
		}
		return ret;
	}
	
	private String getMyGameDesigner(int gameID){
		String ret = null;
		for (GameInfo game : m_list_gameinfo){
			if (game.getGameID() == gameID){
				ret = game.getDesigner();
				break;
			}
		}		
		return ret;
	}
	
	private int getMyGameMaxPlayer(int gameID){
		int ret = -1;
		for (GameInfo game : m_list_gameinfo){
			if (game.getGameID() == gameID){
				ret = game.getMaxPlayer();
				break;
			}
		}		
		return ret;
	}
	
	private int getMyGameMinPlayer(int gameID){
		int ret = -1;
		for (GameInfo game : m_list_gameinfo){
			if (game.getGameID() == gameID){
				ret = game.getMinPlayer();
				break;
			}
		}		
		return ret;
	}
	
	private int getMyGameYear(int gameID){
		int ret = -1;
		for (GameInfo game : m_list_gameinfo){
			if (game.getGameID() == gameID){
				ret = game.getYear();
				break;
			}
		}		
		return ret;
	}
	
	private int getMyGamePlayingTime(int gameID){
		int ret = -1;
		for (GameInfo game : m_list_gameinfo){
			if (game.getGameID() == gameID){
				ret = game.getPlayingTime();
				break;
			}
		}		
		return ret;
	}
	
	private String getWishListGameDesigner(int gameID){
		String ret = null;
		for (GameInfo game : m_wishlist_gameinfo){
			if (game.getGameID() == gameID){
				ret = game.getDesigner();
				break;
			}
		}		
		return ret;
	}
	
	private int getWishListGameMaxPlayer(int gameID){
		int ret = -1;
		for (GameInfo game : m_wishlist_gameinfo){
			if (game.getGameID() == gameID){
				ret = game.getMaxPlayer();
				break;
			}
		}		
		return ret;
	}
	
	private int getWishListGameMinPlayer(int gameID){
		int ret = -1;
		for (GameInfo game : m_wishlist_gameinfo){
			if (game.getGameID() == gameID){
				ret = game.getMinPlayer();
				break;
			}
		}		
		return ret;
	}
	
	private int getWishListGameYear(int gameID){
		int ret = -1;
		for (GameInfo game : m_wishlist_gameinfo){
			if (game.getGameID() == gameID){
				ret = game.getYear();
				break;
			}
		}		
		return ret;
	}
	
	private int getWishListGamePlayingTime(int gameID){
		int ret = -1;
		for (GameInfo game : m_wishlist_gameinfo){
			if (game.getGameID() == gameID){
				ret = game.getPlayingTime();
				break;
			}
		}		
		return ret;
	}
	
	private float getWishListBGGrating(int gameID){
		float ret = 0;
		for (WishGame game : m_wishlist){
			if (game.getGameID() == gameID){
				ret = game.getBggrating();
				break;
			}
		}
		return ret;		
	}
	
	public Object[] getTableRawData(int index){
		//GameInfo game = m_list_gameinfo.get(index);
		CollectedGame game = m_list_collection.get(index);
		TableRawData rawdata = new TableRawData();
		rawdata.setGameID(game.getGameID());
		rawdata.setTitle(game.getName());
		rawdata.setPlay(game.getNumPlays());
		rawdata.setDesigner(this.getMyGameDesigner(game.getGameID()));
		rawdata.setMax(this.getMyGameMaxPlayer(game.getGameID()));
		rawdata.setMin(this.getMyGameMinPlayer(game.getGameID()));
		rawdata.setRank(game.getRank());
		rawdata.setYear(this.getMyGameYear(game.getGameID()));
		rawdata.setTime(this.getMyGamePlayingTime(game.getGameID()));
		rawdata.setRating(game.getRating());
		rawdata.setBayesAverage(game.getBggrating());
		return rawdata.getRawData();
	}
	
	public Object[] getTableRawDataForWishList(int index){
		//GameInfo game = m_wishlist_gameinfo.get(index);
		WishGame game = m_wishlist.get(index);
		TableRawData rawdata = new TableRawData();
		rawdata.setGameID(game.getGameID());
		rawdata.setTitle(game.getName());
		rawdata.setPlay(game.getNumPlays());
		rawdata.setDesigner(this.getWishListGameDesigner(game.getGameID()));
		rawdata.setMax(this.getWishListGameMaxPlayer(game.getGameID()));
		rawdata.setMin(this.getWishListGameMinPlayer(game.getGameID()));
		rawdata.setRank(game.getRank());
		rawdata.setYear(this.getWishListGameYear(game.getGameID()));
		rawdata.setTime(this.getWishListGamePlayingTime(game.getGameID()));
		rawdata.setRating(game.getRating());
		rawdata.setBayesAverage(this.getWishListBGGrating(game.getGameID()));
		return rawdata.getRawData();
	}
	
	public void Update(WareHouse owner) throws BggException, IOException{
		
		owner.setStatus("Getting " + m_username + " collection list.");
		bgg.getSnapShotCollection(m_username);
		
		m_list_collection = bgg.loadSnapshotCollection(m_username);
		
		String txt = "Getting game information. ";
        for (CollectedGame game : m_list_collection) {
        	String file = Library.HOMEDIR + "gamecache/" + String.valueOf(game.getGameID()) + "_gameinfo.xml";
        	if ((!(new File(file).exists()))){
        		owner.setStatus(txt + "[ " + game.getName() + " ]");
        		bgg.getSnapShotCollectionGameInfo(m_username, String.valueOf(game.getGameID()));
        	}
        }
        
        owner.setStatus("Getting " + m_username + " wishlist.");
        bgg.getSnapShotWishList(m_username);
        
        String txt2 = "Getting wishlist game information. ";
        m_wishlist = bgg.loadSnapshotWishList(m_username);
        for (WishGame game : m_wishlist) {
        	String file = Library.HOMEDIR + "gamecache/" + String.valueOf(game.getGameID()) + "_gameinfo.xml";
        	if ((!(new File(file).exists()))){
        		owner.setStatus(txt2 + "[ " + game.getName() + " ]");
        		bgg.getSnapShotWishListGameInfo(m_username, String.valueOf(game.getGameID()));
        	}
        }
        
        
	}
	
	public void updateImage(WareHouse owner){
		int count = 0;
		for (CollectedGame game : m_list_collection){
			try {
				count++;
				owner.setStatus("download thumbnail ... [" + game.getName() + "]");
				String file = Library.HOMEDIR + "imagecache/" + String.valueOf(game.getGameID()) + ".jpg";
				if ( (!(new File(file).exists()))){
					bgg.getFile(game.getThumbnail(), file);
				}
			} catch (BggException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
				owner.setStatus("Error:" + e.getStatusCode() + "[" + e.getMessage() + "]");
			} catch (IOException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}
		}
		for (WishGame game : m_wishlist){
			try {
				count++;
				owner.setStatus("download thumbnail ... [" + game.getName() + "]");
				String file = Library.HOMEDIR + "imagecache/" + String.valueOf(game.getGameID()) + ".jpg";
				if ( (!(new File(file).exists()))){
					bgg.getFile(game.getThumbnail(), file);
				}
			} catch (BggException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
				owner.setStatus("Error:" + e.getStatusCode() + "[" + e.getMessage() + "]");
			} catch (IOException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}
		}
	}
	
	public String[] getImageArray(){
		String[] ret = new String[m_list_collection.size()];
		int count = 0;
		for (CollectedGame game : m_list_collection){
			ret[count] = new String(Library.HOMEDIR + "imagecache/" + String.valueOf(game.getGameID()) + ".jpg");
			count++;
		}
		return ret;
	}
	
	@SuppressWarnings("unchecked")
	public void load(){
		try {
			m_list_collection = bgg.loadSnapshotCollection(m_username);
			RankComparator rankComparator = new RankComparator();
			Collections.sort(m_list_collection, rankComparator);
			m_list_gameinfo = bgg.loadSnapshotCollectionGameInfo(m_username);
			
			m_wishlist = bgg.loadSnapshotWishList(m_username);
			WishListRankComparator wishComparator = new WishListRankComparator();
			Collections.sort(m_wishlist, wishComparator);
			m_wishlist_gameinfo = bgg.loadSnapshotWishListGameInfo(m_username);
			
		} catch (BggException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
		
	}
}

class RankComparator implements Comparator {

	public int compare(Object o1, Object o2) {
		CollectedGame game1 = (CollectedGame)o1;
		CollectedGame game2 = (CollectedGame)o2;
		int ret;

		if (game1.getRank() < 0){
			return 1;
		}else if(game2.getRank() < 0){
			return -1;
		}else{
			ret = game1.getRank() - game2.getRank();
		}
		return ret;
	}
	
	public boolean equals(Object o1, Object o2) {
		CollectedGame game1 = (CollectedGame)o1;
		CollectedGame game2 = (CollectedGame)o2;
		return (game1.getRank() == game2.getRank());
	}
}

class WishListRankComparator implements Comparator {

	public int compare(Object o1, Object o2) {
		WishGame game1 = (WishGame)o1;
		WishGame game2 = (WishGame)o2;
		int ret;

		if (game1.getRank() < 0){
			return 1;
		}else if(game2.getRank() < 0){
			return -1;
		}else{
			ret = game1.getRank() - game2.getRank();
		}
		return ret;
	}
	
	public boolean equals(Object o1, Object o2) {
		WishGame game1 = (WishGame)o1;
		WishGame game2 = (WishGame)o2;
		return (game1.getRank() == game2.getRank());
	}
}
